package main

import (
	"bytes"
	"fmt"
	"log"
	"time"
	"tushare/conf"
	"tushare/service/aliyun/task"

	"tushare/service/aliyunCli"
	"tushare/service/shell"
	serviceSsh "tushare/service/ssh"

	"github.com/spf13/cobra"
	"golang.org/x/crypto/ssh"

	"io/ioutil"
	"os"
	"path/filepath"
	"tushare/model/mysql"
)

/*
cliSsh.exe consumeEcsTask ecsAppTask 消费应用相关任务
cliSsh.exe consumeEcsTask other 消费创建ecs机器任务
*/

func main() {
	mysql.InitDB()
	defer mysql.DB.Close()

	var cmdInstallHadoop = &cobra.Command{
		Use:   "installHadoop",
		Short: "安装hadoop",
		Long:  `安装hadoop`,
		Run: func(cmd *cobra.Command, args []string) {
			accessKeyID := args[0]
			accessKeySecret := args[1]
			keyPairName := args[2]

			conf.AccessKeyID = accessKeyID
			conf.AccessKeySecret = accessKeySecret

			fmt.Println("创建阿里云ecs.c6a.xlarge")
			ci := new(aliyunCli.CreateInstance)
			id := ci.CreateInstance("", "", "")
			time.Sleep(time.Second * 30)
			fmt.Println("阿里云ecs.c6a.xlarge创建成功")

			fmt.Println("阿里云ecs.c6a.xlarge创建公网IP")
			ai := new(aliyunCli.AllocatePublicIpAddress)
			ai.AllocatePublicIpAddress(id)
			time.Sleep(time.Second * 30)
			fmt.Println("阿里云ecs.c6a.xlarge创建公网IP创建成功")

			fmt.Println("阿里云ecs.c6a.xlarge绑定登录秘钥")
			akp := new(aliyunCli.AttachKeyPair)
			akp.AttachKeyPair(id, keyPairName)
			time.Sleep(time.Second * 30)
			fmt.Println("阿里云ecs.c6a.xlarge登录秘钥绑定成功")

			fmt.Println("阿里云ecs.c6a.xlarge启动")
			si := new(aliyunCli.StartInstance)
			si.StartInstance(id)
			time.Sleep(time.Second * 30)
			fmt.Println("阿里云ecs.c6a.xlarge启动成功")

			fmt.Println("开始登录ecs.c6a.xlarge")
			di := new(aliyunCli.DescribeInstances)
			ip := di.DescribeInstances(id)
			// ip := "47.99.99.198"

			host := fmt.Sprintf("%s:22", ip)
			fmt.Println(host)
			//key := []byte(conf.RSAPRIVATEKEY)
			dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
			if err != nil {
				fmt.Println(err)
			}
			filePathStr := fmt.Sprintf("%s/%s", dir, "sshKey.txt")
			content, err := ioutil.ReadFile(filePathStr)
			if err != nil {
				fmt.Println(err)
			}
			key := content

			signer, err := ssh.ParsePrivateKey(key)
			if err != nil {
				log.Fatalf("parse key failed:%v", err)
			}

			// An SSH client is represented with a ClientConn.
			//
			// To authenticate with the remote server you must pass at least one
			// implementation of AuthMethod via the Auth field in ClientConfig,
			// and provide a HostKeyCallback.
			config := &ssh.ClientConfig{
				User:            "root",
				Auth:            []ssh.AuthMethod{ssh.PublicKeys(signer)},
				HostKeyCallback: ssh.InsecureIgnoreHostKey(),
				Timeout:         time.Second * 3600,
			}
			client, err := ssh.Dial("tcp", host, config)
			if err != nil {
				log.Fatal("Failed to dial: ", err)
			}
			defer client.Close()

			// Each ClientConn can support multiple interactive sessions,
			// represented by a Session.
			session, err := client.NewSession()
			if err != nil {
				log.Fatal("Failed to create session: ", err)
			}
			defer session.Close()

			fmt.Println("开始安装Hadoop测试环境")
			// Once a Session is created, you can execute a single command on
			// the remote side using the Run method.
			var b bytes.Buffer
			session.Stdout = &b
			installHadoop := (new(shell.InstallApp)).InstallHadoop()
			if err := session.Run(installHadoop); err != nil {
				log.Fatal("Failed to run: " + err.Error())
			}

			fmt.Println("Hadoop测试环境安装成功")
		},
	}

	var cmdCreateKeyPair = &cobra.Command{
		Use:   "createKeyPair",
		Short: "创建登录秘钥",
		Long:  `创建登录秘钥`,
		Run: func(cmd *cobra.Command, args []string) {
			if len(args) == 0 {
				fmt.Println("请输入秘钥名称，密钥对名称。长度为2~128个英文或中文字符。必须以大小字母或中文开头，不能以http:// 或https:// 开头。可以包含数字、半角冒号（:）、下划线（_）或者短划线（-）。")
				return
			}
			accessKeyID := args[0]
			accessKeySecret := args[1]
			keyPairName := args[2]
			conf.AccessKeyID = accessKeyID
			conf.AccessKeySecret = accessKeySecret

			ckp := new(aliyunCli.CreateKeyPair)
			ckp.CreateKeyPair(keyPairName)
		},
	}

	var cmdConsumeEcsTask = &cobra.Command{
		Use:   "consumeEcsTask",
		Short: "消费ecs任务",
		Long:  `消费ecs任务`,
		Run: func(cmd *cobra.Command, args []string) {
			taskType := args[0]
			for {
				if taskType == "ecsAppTask" {
					task.ConsumeAppTask()
				} else {
					task.ConsumeTask()
				}

				time.Sleep(time.Millisecond * 20)
			}
		},
	}

	var cmdDeleteInstance = &cobra.Command{
		Use:   "deleteInstance",
		Short: "删除到期的实例",
		Long:  `删除到期的实例`,
		Run: func(cmd *cobra.Command, args []string) {
			for {
				task.DeleteInstance()
				time.Sleep(time.Second * 20)
			}
		},
	}

	var cmdExecCommandTest = &cobra.Command{
		Use:   "execCommandTest",
		Short: "执行命令测试",
		Long:  `执行命令测试`,
		Run: func(cmd *cobra.Command, args []string) {
			sh := new(serviceSsh.Ssh)
			sh.ExecCommandTest()
		},
	}

	var rootCmd = &cobra.Command{Use: "app"}
	rootCmd.AddCommand(cmdInstallHadoop)
	rootCmd.AddCommand(cmdCreateKeyPair)
	rootCmd.AddCommand(cmdConsumeEcsTask)
	rootCmd.AddCommand(cmdDeleteInstance)
	rootCmd.AddCommand(cmdExecCommandTest)
	rootCmd.Execute()
}
